/*
* tedi2lang header file
* Copyright (C) <2022>  <alkeon> [alkeon@autistici.org]
   
* Texdi is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Texdi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with tedi2lang.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __TEDI2LANG__
#define __TEDI2LANG__
#include <iostream>
#include <string>
using namespace std;
struct tags_definition {
	tags_definition(){}
	string start_heading_first_level_tag;
	string start_heading_second_level_tag;
	string start_heading_third_level_tag;
	string start_heading_fourth_level_tag;
	
	string end_heading_first_level_tag;
	string end_heading_second_level_tag;
	string end_heading_third_level_tag;
	string end_heading_fourth_level_tag;
	
	string start_list_tag;
	string end_list_tag;
	string list_item_tag;
	
	string start_container_tag;
	string middle_container_tag;
	string end_container_tag;
	
	string start_link_tag;
	string middle_link_tag;
	string end_link_tag;
	
	string start_image_tag;
	string middle_image_tag;
	string end_image_tag;
	
	string start_table_tag;
	string end_table_tag;
	string start_table_row_tag;
	string end_table_row_tag;
	string start_table_data_tag;
	string end_table_data_tag;

	string end_paragraph_tag;
};

class tedi2lang{
	public:
		tedi2lang(tags_definition td);
		tedi2lang();

		virtual ~tedi2lang() = default;

		virtual string convert(string text, string header, string footer);
		virtual string convert_line(string& line);
		
		virtual string convert_line_heading(string& line, size_t hash_position);

		virtual string convert_line_list_start(string& line);
		virtual void convert_line_list_item(string& line, size_t li);
		virtual string convert_line_list_end(string& line);

		virtual void convert_line_quote(string& line);

		virtual void convert_unquoted_tags(string& line);
		virtual void convert_line_block(string& line);
		virtual void convert_line_image(string& line);
		virtual void convert_line_link(string& line);

		virtual string convert_line_table(string& line, size_t first_pipe);
		virtual string convert_line_table_row(string& line);
		virtual string convert_end_table(string& line);
		virtual string convert_end_table_control_tags(string& line);

		virtual string convert_line_ending(string& line);
		virtual string convert_line_control_tags(string& line);
		
		bool is_first_tag(string& line, int position);
		bool is_tag_escaped(string& line, size_t position);
		virtual size_t get_not_escaped_tag(string& line, string character_find, size_t position = string::npos);
		virtual int main_tag(string& line);
		virtual size_t correct_position(string line, unsigned position, char starting_char, char ending_char);

		virtual void check_ending_container(string& line);

		virtual bool found(size_t position){ return (position != string::npos); }
		
		string strip_escaping(string line);
		
		int replace(string& source, const string& find, const string& replace);
		
	protected:
		bool _is_converting_table;
		int _is_unordered_list;
		bool _has_block;
		int _open_brackets;
		
		const string _start_heading_first_level_tag;
		const string _start_heading_second_level_tag;
		const string _start_heading_third_level_tag;
		const string _start_heading_fourth_level_tag;
		
		const string _end_heading_first_level_tag;
		const string _end_heading_second_level_tag;
		const string _end_heading_third_level_tag;
		const string _end_heading_fourth_level_tag;
		
		const string _start_list_tag;
		const string _list_item_tag;
		const string _end_list_tag;
		
		const string _start_container_tag;
		const string _middle_container_tag;
		const string _end_container_tag;
		
		const string _start_link_tag;
		const string _middle_link_tag;
		const string _end_link_tag;
		
		const string _start_image_tag;
		const string _middle_image_tag;
		const string _end_image_tag;
		
		const string _start_table_tag;
		const string _end_table_tag;
		const string _start_table_row_tag;
		const string _end_table_row_tag;
		const string _start_table_data_tag;
		const string _end_table_data_tag;

		const string _end_paragraph_tag;
		
};

#endif
